<script setup lang="ts">
import Motion from "./utils/motion";
import { useRouter } from "vue-router";
import { message } from "@/utils/message";
import { loginRules, REGEXP_PHONE } from "./utils/rule";
import { ref, reactive, toRaw, onMounted } from "vue";
import { debounce } from "@pureadmin/utils";
import { useNav } from "@/layout/hooks/useNav";
import { useEventListener } from "@vueuse/core";
import type { FormInstance, FormRules } from "element-plus";
import { useLayout } from "@/layout/hooks/useLayout";
import { useUserStoreHook } from "@/store/modules/user";
import { send as sendUser } from "@/api/user";
import { changePassword, send } from "@/api/password";
import { initRouter, getTopMenu } from "@/router/utils";
import { bg, avatar, illustration } from "./utils/static";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";

import dayIcon from "@/assets/svg/day.svg?component";
import darkIcon from "@/assets/svg/dark.svg?component";
import Lock from "~icons/ri/lock-fill";
import User from "~icons/ri/user-3-fill";

defineOptions({
  name: "Login"
});

const router = useRouter();
const loading = ref(false);
const disabled = ref(false);
const passwordFormRef = ref<FormInstance>();
const verifyFormRef = ref<FormInstance>();

const { initStorage } = useLayout();
initStorage();

const { dataTheme, overallStyle, dataThemeChange } = useDataThemeChange();
dataThemeChange(overallStyle.value);
const { title } = useNav();

const ruleForm = reactive({
  contact_phone: "",
  password: "",
  captcha: "",
  verifyCode: ""
});

// 当前激活的选项卡
const activeTab = ref("password");

// 图形验证码图片URL（由后端生成）
const captchaUrl = ref("");

// 自动登录
const autoLogin = ref(false);

// 发送验证码倒计时
const countdown = ref(0);
const canSendCode = ref(true);

// 忘记密码相关
const forgotPasswordVisible = ref(false);
const forgotPasswordForm = reactive({
  contact_phone: "",
  captcha: "",
  new_password: "",
  confirm_password: ""
});
const forgotPasswordFormRef = ref<FormInstance>();
const forgotPasswordSubmitting = ref(false);
const forgotPasswordCountdown = ref(0);
const canSendForgotPasswordCode = ref(true);

// 忘记密码表单验证规则
const forgotPasswordRules = reactive<FormRules>({
  contact_phone: [
    {
      required: true,
      message: "请输入手机号",
      trigger: "blur"
    },
    {
      pattern: REGEXP_PHONE,
      message: "请输入正确的手机号格式",
      trigger: "blur"
    }
  ],
  captcha: [
    {
      required: true,
      message: "请输入验证码",
      trigger: "blur"
    }
  ],
  new_password: [
    {
      required: true,
      message: "请输入新密码",
      trigger: "blur"
    },
    {
      min: 6,
      message: "新密码长度不能少于6位",
      trigger: "blur"
    }
  ],
  confirm_password: [
    {
      required: true,
      message: "请确认新密码",
      trigger: "blur"
    }
  ]
});

// 发送验证码
const sendVerifyCode = async () => {
  if (!ruleForm.contact_phone) {
    message("请先输入手机号", { type: "warning" });
    return;
  }

  // 验证手机号格式
  if (!REGEXP_PHONE.test(ruleForm.contact_phone)) {
    message("请输入正确的手机号格式", { type: "warning" });
    return;
  }

  try {
    // 调用发送短信验证码接口
    const res: any = await sendUser({
      mobile: ruleForm.contact_phone,
      event: "login"
    });
    if (res.success || res.code === 1) {
      message("验证码发送成功", { type: "success" });
      // 开始倒计时
      countdown.value = 60;
      canSendCode.value = false;

      const timer = setInterval(() => {
        countdown.value--;
        if (countdown.value <= 0) {
          clearInterval(timer);
          canSendCode.value = true;
        }
      }, 1000);
    } else {
      message(res.msg || "验证码发送失败", { type: "error" });
    }
  } catch (error) {
    message("验证码发送失败", { type: "error" });
    console.error("发送验证码错误:", error);
  }
};

// 密码登录
const onPasswordLogin = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;

  await formEl.validate(valid => {
    if (valid) {
      loading.value = true;

      const loginData = {
        contact_phone: ruleForm.contact_phone,
        password: ruleForm.password,
        captcha: ruleForm.captcha
      };

      useUserStoreHook()
        .loginByUsername(loginData)
        .then((res: any) => {
          if (res.success) {
            // 检查是否是首次登录
            if (res.data.is_login === 0) {
              message("首次登录需通过验证登录", { type: "warning" });
              loading.value = false;
              return;
            }

            // 获取后端路由
            return initRouter().then(() => {
              disabled.value = true;
              router
                .push(getTopMenu(true).path)
                .then(() => {
                  message("登录成功", { type: "success" });
                })
                .finally(() => (disabled.value = false));
            });
          } else {
            // 登录失败时自动刷新图形验证码
            refreshCaptcha();
            // 清空图形验证码输入框
            ruleForm.captcha = "";
            // 根据后端返回的错误信息显示具体错误
            const errorMsg = res.msg || res.message || "登录失败";
            message(errorMsg, { type: "error" });
          }
        })
        .catch(error => {
          console.error("登录错误:", error);
          // 登录失败时自动刷新图形验证码
          refreshCaptcha();
          // 清空图形验证码输入框
          ruleForm.captcha = "";
          // 根据错误对象显示具体错误信息
          let errorMsg = "登录失败";
          if (error?.response?.data?.msg) {
            errorMsg = error.response.data.msg;
          } else if (error?.response?.data?.message) {
            errorMsg = error.response.data.message;
          } else if (error?.message) {
            errorMsg = error.message;
          } else if (typeof error === "string") {
            errorMsg = error;
          }
          message(errorMsg, { type: "error" });
        })
        .finally(() => (loading.value = false));
    }
  });
};

// 验证码登录
const onVerifyLogin = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate(valid => {
    if (valid) {
      loading.value = true;
      useUserStoreHook()
        .loginByMobile({
          contact_phone: ruleForm.contact_phone,
          captcha: ruleForm.verifyCode
        })
        .then((res: any) => {
          if (res.success) {
            // 获取后端路由
            return initRouter().then(() => {
              disabled.value = true;
              router
                .push(getTopMenu(true).path)
                .then(() => {
                  message("登录成功", { type: "success" });
                })
                .finally(() => (disabled.value = false));
            });
          } else {
            // 登录失败时清空验证码输入框
            ruleForm.verifyCode = "";
            // 根据后端返回的错误信息显示具体错误
            const errorMsg = res.msg || res.message || "登录失败";
            message(errorMsg, { type: "error" });
          }
        })
        .catch(error => {
          // 登录失败时清空验证码输入框
          ruleForm.verifyCode = "";
          // 根据错误对象显示具体错误信息
          let errorMsg = "登录失败";
          if (error?.response?.data?.msg) {
            errorMsg = error.response.data.msg;
          } else if (error?.response?.data?.message) {
            errorMsg = error.response.data.message;
          } else if (error?.message) {
            errorMsg = error.message;
          } else if (typeof error === "string") {
            errorMsg = error;
          }
          message(errorMsg, { type: "error" });
          console.error("登录错误:", error);
        })
        .finally(() => (loading.value = false));
    }
  });
};

// 统一的登录方法，根据当前选项卡调用不同的登录逻辑
const onLogin = async (formEl: FormInstance | undefined) => {
  if (activeTab.value === "password") {
    await onPasswordLogin(formEl);
  } else {
    await onVerifyLogin(formEl);
  }
};

// 获取图形验证码
const getCaptchaImage = () => {
  // 直接拼接基础URL和接口路径作为图片地址
  const baseUrl = import.meta.env.VITE_API_URL || window.location.origin;
  captchaUrl.value = `${baseUrl}/api/common/captcha`;
};

// 刷新图形验证码
const refreshCaptcha = () => {
  // 添加时间戳参数避免浏览器缓存
  const baseUrl = import.meta.env.VITE_API_URL || window.location.origin;
  captchaUrl.value = `${baseUrl}/api/common/captcha?t=${Date.now()}`;
};

// 显示忘记密码弹框
const showForgotPassword = () => {
  forgotPasswordVisible.value = true;
  // 重置表单
  forgotPasswordForm.contact_phone = "";
  forgotPasswordForm.captcha = "";
  forgotPasswordForm.new_password = "";
  forgotPasswordForm.confirm_password = "";
  forgotPasswordCountdown.value = 0;
  canSendForgotPasswordCode.value = true;
};

// 关闭忘记密码弹框
const closeForgotPassword = () => {
  forgotPasswordVisible.value = false;
};

// 发送忘记密码验证码
const sendForgotPasswordCode = async () => {
  if (!forgotPasswordForm.contact_phone) {
    message("请先输入手机号", { type: "warning" });
    return;
  }

  // 验证手机号格式
  if (!REGEXP_PHONE.test(forgotPasswordForm.contact_phone)) {
    message("请输入正确的手机号格式", { type: "warning" });
    return;
  }

  try {
    // 调用发送短信验证码接口
    const res = await send({
      mobile: forgotPasswordForm.contact_phone,
      event: "changepwd"
    });
    if (res.code === 1) {
      message("验证码发送成功", { type: "success" });
      // 开始倒计时
      forgotPasswordCountdown.value = 60;
      canSendForgotPasswordCode.value = false;

      const timer = setInterval(() => {
        forgotPasswordCountdown.value--;
        if (forgotPasswordCountdown.value <= 0) {
          clearInterval(timer);
          canSendForgotPasswordCode.value = true;
        }
      }, 1000);
    } else {
      message(res.msg || "验证码发送失败", { type: "error" });
    }
  } catch (error) {
    message("验证码发送失败", { type: "error" });
    console.error("发送验证码错误:", error);
  }
};

// 确认修改忘记密码
const confirmForgotPassword = async () => {
  if (!forgotPasswordFormRef.value) return;

  try {
    const valid = await forgotPasswordFormRef.value.validate();
    if (!valid) {
      message("请检查表单填写是否正确", { type: "warning" });
      return;
    }

    // 验证新密码和确认密码是否一致
    if (
      forgotPasswordForm.new_password !== forgotPasswordForm.confirm_password
    ) {
      message("新密码和确认密码不一致", { type: "error" });
      return;
    }

    forgotPasswordSubmitting.value = true;

    // 调用修改密码接口
    const res = await changePassword({
      contact_phone: forgotPasswordForm.contact_phone,
      new_password: forgotPasswordForm.new_password,
      captcha: forgotPasswordForm.captcha
    });

    if (res.code === 1) {
      message("密码修改成功", { type: "success" });
      closeForgotPassword();
    } else {
      message(res.msg || "密码修改失败，请重试", { type: "error" });
    }
  } catch (error) {
    console.error("修改密码失败:", error);
    message("修改密码失败，请稍后重试", { type: "error" });
  } finally {
    forgotPasswordSubmitting.value = false;
  }
};

const immediateDebounce: any = debounce(
  formRef => onLogin(formRef),
  1000,
  true
);

useEventListener(document, "keydown", ({ code }) => {
  if (
    ["Enter", "NumpadEnter"].includes(code) &&
    !disabled.value &&
    !loading.value
  ) {
    // 根据当前选项卡使用对应的表单引用
    const currentFormRef =
      activeTab.value === "password"
        ? passwordFormRef.value
        : verifyFormRef.value;
    immediateDebounce(currentFormRef);
  }
});

// 组件挂载时获取图形验证码
onMounted(() => {
  getCaptchaImage();
});
</script>

<template>
  <div class="select-none">
    <img :src="bg" class="wave" />
    <div class="flex-c absolute right-5 top-3">
      <!-- 主题 -->
      <el-switch
        v-model="dataTheme"
        inline-prompt
        :active-icon="dayIcon"
        :inactive-icon="darkIcon"
        @change="dataThemeChange"
      />
    </div>
    <div class="login-container">
      <div class="img">
        <component :is="toRaw(illustration)" />
      </div>
      <div class="login-box">
        <div class="login-form">
          <avatar class="avatar" />
          <Motion>
            <h2 class="outline-hidden">{{ title }}</h2>
          </Motion>
          <div style="font-size: 14px; color: red; margin-bottom: 10px">
            温馨提示:
          </div>
          <div style="font-size: 12px; color: red; margin-bottom: 10px">
            首次登录需通过“验证登录”，修改密码后可通过任意登录方式
          </div>
          <!-- Tabs选项卡 -->
          <el-tabs v-model="activeTab" class="login-tabs">
            <!-- 密码登录选项卡 -->
            <el-tab-pane label="密码登录" name="password">
              <el-form
                ref="passwordFormRef"
                :model="ruleForm"
                :rules="loginRules"
                size="large"
              >
                <Motion :delay="100">
                  <el-form-item prop="contact_phone">
                    <el-input
                      v-model="ruleForm.contact_phone"
                      clearable
                      placeholder="请输入展商联系人电话号码"
                      :prefix-icon="useRenderIcon(User)"
                    />
                  </el-form-item>
                </Motion>

                <Motion :delay="150">
                  <el-form-item prop="captcha">
                    <div class="captcha-container">
                      <el-input
                        v-model="ruleForm.captcha"
                        clearable
                        placeholder="请输入图形验证码"
                        style="flex: 1; margin-right: 10px"
                      />
                      <img
                        :src="captchaUrl"
                        alt="图形验证码"
                        class="captcha-image"
                        @click="refreshCaptcha"
                      />
                    </div>
                  </el-form-item>
                </Motion>

                <Motion :delay="200">
                  <el-form-item prop="password">
                    <el-input
                      v-model="ruleForm.password"
                      clearable
                      show-password
                      placeholder="请输入密码"
                      :prefix-icon="useRenderIcon(Lock)"
                    />
                  </el-form-item>
                </Motion>

                <Motion :delay="250">
                  <div class="login-options">
                    <el-checkbox v-model="autoLogin">自动登录</el-checkbox>
                    <span class="forgot-password" @click="showForgotPassword"
                      >忘记密码了？</span
                    >
                  </div>
                </Motion>

                <Motion :delay="300">
                  <el-button
                    class="w-full!"
                    size="default"
                    :loading="loading"
                    :disabled="disabled"
                    style="
                      background-color: #0bb2d4;
                      border-color: #0bb2d4;
                      color: #fff;
                    "
                    @click="onLogin(passwordFormRef)"
                  >
                    立即登录
                  </el-button>
                </Motion>
              </el-form>
            </el-tab-pane>

            <!-- 验证登录选项卡 -->
            <el-tab-pane label="验证登录" name="verify">
              <el-form
                ref="verifyFormRef"
                :model="ruleForm"
                :rules="loginRules"
                size="large"
              >
                <Motion :delay="100">
                  <el-form-item prop="contact_phone">
                    <div class="verify-container">
                      <el-input
                        v-model="ruleForm.contact_phone"
                        clearable
                        placeholder="请输入手机号"
                        :prefix-icon="useRenderIcon(User)"
                        style="flex: 1; margin-right: 10px"
                      />
                      <el-button
                        :disabled="!canSendCode"
                        style="
                          background-color: #0bb2d4;
                          border-color: #0bb2d4;
                          color: #fff;
                        "
                        @click="sendVerifyCode"
                      >
                        {{ canSendCode ? "发送验证码" : `${countdown}s` }}
                      </el-button>
                    </div>
                  </el-form-item>
                </Motion>

                <Motion :delay="150">
                  <el-form-item prop="verifyCode">
                    <el-input
                      v-model="ruleForm.verifyCode"
                      clearable
                      placeholder="请输入验证码"
                      :prefix-icon="useRenderIcon(Lock)"
                    />
                  </el-form-item>
                </Motion>

                <Motion :delay="200">
                  <el-button
                    class="w-full mt-4!"
                    size="default"
                    :loading="loading"
                    :disabled="disabled"
                    style="
                      background-color: #0bb2d4;
                      border-color: #0bb2d4;
                      color: #fff;
                    "
                    @click="onLogin(verifyFormRef)"
                  >
                    立即登录
                  </el-button>
                </Motion>
              </el-form>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </div>

    <!-- 忘记密码弹框 -->
    <el-dialog
      v-model="forgotPasswordVisible"
      title="忘记密码"
      width="670px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <el-form
        ref="forgotPasswordFormRef"
        :model="forgotPasswordForm"
        :rules="forgotPasswordRules"
        label-width="100px"
        size="large"
      >
        <el-form-item label="手机号:" prop="contact_phone">
          <div class="phone-input-container">
            <el-input
              v-model="forgotPasswordForm.contact_phone"
              placeholder="请输入手机号"
              style="width: 300px; margin-right: 10px"
            />
            <el-button
              size="large"
              :disabled="!canSendForgotPasswordCode"
              style="width: 140px; min-width: 140px"
              @click="sendForgotPasswordCode"
            >
              {{
                canSendForgotPasswordCode
                  ? "发送验证码"
                  : `${forgotPasswordCountdown}s`
              }}
            </el-button>
          </div>
        </el-form-item>

        <el-form-item label="验证码:" prop="captcha">
          <el-input
            v-model="forgotPasswordForm.captcha"
            placeholder="请输入验证码"
            style="width: 450px"
          />
        </el-form-item>

        <el-form-item label="新密码:" prop="new_password">
          <el-input
            v-model="forgotPasswordForm.new_password"
            type="password"
            placeholder="请输入新密码"
            show-password
            style="width: 450px"
          />
        </el-form-item>

        <el-form-item label="确认密码:" prop="confirm_password">
          <el-input
            v-model="forgotPasswordForm.confirm_password"
            placeholder="请确认新密码"
            type="password"
            show-password
            style="width: 450px"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeForgotPassword">取消</el-button>
          <el-button
            type="primary"
            :loading="forgotPasswordSubmitting"
            :disabled="forgotPasswordSubmitting"
            @click="confirmForgotPassword"
          >
            确认修改
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
@import url("@/style/login.css");
</style>

<style lang="scss" scoped>
:deep(.el-input-group__append, .el-input-group__prepend) {
  padding: 0;
}

/* 登录选项卡样式 */
.login-tabs {
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
}

:deep(.el-tabs__header) {
  margin-bottom: 20px;
}

:deep(.el-tabs__nav-wrap) {
  justify-content: center;
  border-bottom: none;
  width: 100%;
}

:deep(.el-tabs__active-bar) {
  display: none !important;
}

:deep(.el-tabs__nav) {
  width: 100%;
  display: flex;
  justify-content: center;
}

:deep(.el-tabs__item) {
  font-size: 16px;
  font-weight: 500;
  width: 200px;
  text-align: center;
  min-width: 0;
  border: 1px solid #0bb2d4;
  border-bottom: none;
  border-radius: 4px 4px 0 0;
  margin-right: 20px;
  background-color: #0bb2d4;
  color: #fff;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  height: 40px;
  line-height: 40px;
  padding: 0 !important;
  box-sizing: border-box !important;
}

:deep(.el-tabs__item span) {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 100% !important;
  height: 100% !important;
}

:deep(.el-tabs__item:last-child) {
  margin-right: 0;
}

:deep(.el-tabs__item.is-active) {
  background-color: #fff;
  color: #000;
}

:deep(.el-tabs__item) {
  transition: none !important;
}

/* 忘记密码弹框样式 */
.phone-input-container {
  display: flex;
  align-items: center;
}

.forgot-password {
  color: #0bb2d4;
  cursor: pointer;
  text-decoration: underline;
}

.forgot-password:hover {
  color: #0891a3;
}

.dialog-footer {
  text-align: center;
}

:deep(.el-dialog__body) {
  padding: 20px 30px;
}

:deep(.el-dialog__footer) {
  padding: 10px 30px 20px;
}

:deep(.el-tabs__nav) {
  transition: none !important;
}

/* 图形验证码容器 */
.captcha-container {
  display: flex;
  align-items: center;
  width: 100%;
}

.captcha-image {
  width: 100px;
  height: 40px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  cursor: pointer;
  object-fit: cover;
}

/* 验证码发送容器 */
.verify-container {
  display: flex;
  align-items: center;
  width: 100%;
}

/* 登录选项 */
.login-options {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.forgot-password {
  color: #409eff;
  cursor: pointer;
  font-size: 14px;
}

.forgot-password:hover {
  text-decoration: underline;
}

/* 响应式处理 */
@media (max-width: 768px) {
  .captcha-image {
    width: 80px;
    height: 36px;
  }

  .verify-container .el-button {
    padding: 8px 12px;
    font-size: 12px;
  }
}
</style>
